package ctwing

import (
	"context"
	"encoding/hex"
	"errors"
	"sort"
	"strings"
	"time"

	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/frame/g"
)

// Sign 电信生成签名 params = "a=1&c=3&b=2" body = "{\"name\":\"xf\",\"age\":\"dd\"}"   appSecret必填
func Sign(appKey, appSecret, params, body string) (string, string, error) {
	current := getCurrentTimestamp()

	var newParams string
	if params != "" {
		pa, err := order(params)
		if err != nil {
			return "", "", err
		}
		newParams = pa
	}

	if appSecret == "" {
		return "", "", errors.New("appSecret不能为空")
	}
	md5 := signMD5(newParams + body + appSecret + current)
	return current, md5, nil
}

func getCurrentTimestamp() string {
	return time.Now().UTC().Format(Date_Format_Pattern)
}
func order(params string) (string, error) {
	kvs := strings.Split(params, "&")
	if len(kvs) == 0 {
		return "", errors.New("URL 参数不规范")
	}
	var mv map[string]string = make(map[string]string)
	var keys []string
	for _, kv := range kvs {
		kav := strings.Split(kv, "=")
		if len(kav) != 2 {
			return "", errors.New("URL 参数不规范")
		}
		mv[kav[0]] = kav[1]
		keys = append(keys, kav[0])
	}

	sort.Strings(keys)
	var str []string
	for _, v := range keys {
		sp := []string{}
		sp = append(sp, v, mv[v])
		str = append(str, strings.Join(sp, "="))
	}
	return strings.Join(str, "&"), nil
}
func signMD5(req string) string {
	res := gmd5.MustEncryptString(req)
	return hex.EncodeToString([]byte(res))
}

func HttpPost(appKey, appSecret, params, body, subUrl string) (string, error) {
	current, sign, err := Sign(appKey, appSecret, params, body)
	if err != nil {
		return "", err
	}

	m := map[string]string{
		"AppKey":    appKey,
		"Timestamp": current,
		"Sign":      sign,
	}
	var url string = Ctwing_BaseUrl + subUrl
	if params != "" {
		url = url + "?" + params
	}
	resp, err := g.Client().Header(m).Post(context.Background(), url, body)
	if err != nil {
		return "", err
	}
	defer resp.Close()
	return resp.ReadAllString(), nil

}
